package com.lucien.framework.shiro.realm;

import com.lucien.common.utils.StringUtils;
import com.lucien.framework.exception.GlobalException;
import com.lucien.framework.shiro.domain.JwtToken;
import com.lucien.system.domain.SysUser;
import com.lucien.system.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Author: Lucien
 * @Description: 自定义realm 实习认证 授权
 * @Date: Created in 2021/5/2
 */
public class JwtRealm extends AuthorizingRealm {

    private static final Logger log = LoggerFactory.getLogger(JwtRealm.class);

    @Autowired
    private SysUserService userService;

    /**
     * 限定Realm 只处理自定义的 JwtToken
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取当前用户
        SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();

//        Set<String> roleSet = new HashSet<>();
        //查询数据库，获取用户的角色信息
        String role = userService.getRole(sysUser.getUsername()).getRole();
//        roleSet.add(role);
        //查询数据库，获取用户的权限信息
        System.out.println("jwtrealm获取用户角色："+role);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(role);
//        info.setRoles(roleSet);
//        info.setStringPermissions();

        log.info("--------赋予角色成功------");
        return info;
    }

    /**
     * SimpleAuthenticationInfo 可返回任意值，
     * 密码校验时不会用到它
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        JwtToken jwtToken = (JwtToken) token;
        if (jwtToken.getPrincipal() == null) {
            System.out.println(jwtToken.toString());
            throw new GlobalException("Jwt Token异常");
        }

        String username = jwtToken.getPrincipal().toString();

        SysUser sysUser = userService.selectByUsername(username);

        if (StringUtils.isNull(sysUser)) {
            throw new UnknownAccountException("用户不存在");
        }

        if (sysUser.getIsLocked()){
            throw new LockedAccountException("该用户已被锁定,暂时无法登录！");
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), getName());

        return info;
    }
}
